package com.gaofei.controller;

import cn.hutool.http.HttpUtil;
import com.gaofei.domain.ActivitiVo;
import com.gaofei.domain.UserTask;
import com.gaofei.service.LeaveService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricDetail;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.batik.transcoder.TranscoderException;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@CrossOrigin
@Slf4j
public class LeaveController {

    @Resource
    private LeaveService leaveService;

    @Autowired
    private RuntimeService runtimeService;


    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private RepositoryService repositoryService;


    @RequestMapping("ask4Leave")
    ////////////////////////接收前端传过来的json类型的数据-->封装到这个实体类
    public Object ask4Leave(@RequestBody ActivitiVo activitiVo){

        //1.将请假表单数据保存到数据库
       boolean b =  leaveService.save(activitiVo);
        HashMap<String, Object> map = new HashMap<>();
        map.put("username",activitiVo.getUsername());
        //////////bussinessKey 业务key  请假    贷款
        //2.开启流程
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia",activitiVo.getId()+"",map);
        log.info("流程定义id:{}",processInstance.getProcessDefinitionId());
        log.info("流程实例id:{}",processInstance.getId());
        log.info("当前活动id:{}",processInstance.getActivityId());

        return "提交申请成功!";
    }

    /**
     * 查询责任人待办任务
     * @param activitiVo
     * @return
     */

    @RequestMapping("queryTaskByAssignee")
    public Object queryTaskByAssignee(@RequestBody ActivitiVo activitiVo){

        List<UserTask> userTasks = new ArrayList<>();

        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("qingjia")
                .taskAssignee(activitiVo.getUsername())
                .list();

        list.forEach(task->{
            //遍历集合,把集合中的数据拿出来,放进咱们自己的实体类,添加到集合
            UserTask userTask = new UserTask();
            HashMap<String, Object> map = new HashMap<>();
            map.put("id", task.getId());
            map.put("name", task.getName());
            map.put("assignee", task.getAssignee());
            map.put("description", task.getDescription());
            map.put("processDefinitionId", task.getProcessDefinitionId());
            map.put("processInstanceId", task.getProcessInstanceId());
            map.put("parentTaskId", task.getParentTaskId());
            //获取申请人相关信息---从业务表中去拿
            HistoricProcessInstance historicTaskInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            String businessKey = historicTaskInstance.getBusinessKey();
            //根据这个业务的key,作为业务表的主键查询业务数据
            ActivitiVo activitiVo1 =  leaveService.findLeaveById(Integer.parseInt(businessKey));
            map.put("applyUser", activitiVo1.getUsername());
            map.put("cause", activitiVo1.getCause());
            map.put("holiday", activitiVo1.getHoliday());
            userTask.setHistoricProcessInstance(historicTaskInstance);
            userTask.setTask(map);
            userTasks.add(userTask);
        });
        return userTasks;
    }

    /**
     * 处理任务/同意/驳回
     * @param activitiVo
     * @return
     */


    @RequestMapping("doTask")
    public Object doTask(@RequestBody ActivitiVo activitiVo){
        Map<String, Object> map = new HashMap<>();
        map.put("appro",activitiVo.getApprove());
        taskService.complete(activitiVo.getTaskId(),map);



        return "success";
    }

    @RequestMapping("viewTask")
    public void viewTask(String processInstanceId , HttpServletResponse response) throws IOException, TranscoderException {
        InputStream in = this.getProcessDiagram(processInstanceId);

        //svg 转  png
        byte[] streamBytes = IOUtils.toByteArray(in);
        ByteArrayOutputStream byteArrayOutputStream = svgToPng(streamBytes);
        String imageName = "image" + Instant.now().getEpochSecond() + ".png";
//        byteArrayOutputStream.writeTo(new FileOutputStream(new File("D:/images/"+imageName)));
//        FileInputStream fis = new FileInputStream(new File("D:/images/" + imageName));
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

        response.setContentType("text/html; charset=UTF-8");
        response.setContentType("image/png");
        response.addHeader("Content-Disposition", "inline; filename=" + imageName);
        ServletOutputStream outputStream = response.getOutputStream();
        IOUtils.copy(byteArrayInputStream, outputStream);
        outputStream.close();
    }


    private ByteArrayOutputStream svgToPng(byte[] streamBytes) throws TranscoderException, IOException {

        PNGTranscoder t = new PNGTranscoder();

        TranscoderInput input = new TranscoderInput(new ByteArrayInputStream(streamBytes));

        ByteArrayOutputStream ostream = new ByteArrayOutputStream();

        TranscoderOutput output = new TranscoderOutput(ostream);

        t.transcode(input, output);

        ostream.flush();
        return ostream;

    }

    /**
     * Get Process instance diagram
     */
    public InputStream getProcessDiagram(String processInstanceId) {
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();

        List<String> highLightedActivities = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).list().stream().map(item -> item.getActivityId()).collect(Collectors.toList());

        // null check
        if (processInstance != null) {
            // get process model
            BpmnModel model = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
            if (model != null && model.getLocationMap().size() > 0) {
                ProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
                // 生成流程图 已启动的task 高亮
                return generator.generateDiagram(model,
                        runtimeService.getActiveActivityIds(processInstanceId), highLightedActivities, "simsun", "simsun", "simsun");
                // 生成流程图 都不高亮
//                return generator.generateDiagram(model,Collections.<String>emptyList());
            }
        }
        return null;
    }
}
